package com.imageprocess;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import com.imageprocess.tools.FileHelper;
import com.imageprocess.tools.ImageHelper;
import com.imageprocess.ui.ImageZoomView;
import com.imageprocess.ui.SimpleZoomListener;
import com.imageprocess.ui.TabMenu;
import com.imageprocess.ui.ZoomState;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ZoomControls;

import jjil.algorithm.*;

import jjil.android.RgbImageAndroid;
import jjil.core.Error;
import jjil.core.Gray8Image;
import jjil.core.RgbImage;

public class MainCanvas extends Activity {
    // 常量
    private static final String TAG = "MainCanvas";
    private static final int REQUEST_PHOTO_LIBRARY = 1;
    private static final int CROP_IMAGE = 2;
    private static final int FORMAT_JPG = 0;
    private static final int FORMAT_PNG = 1;

    TabMenu.MenuBodyAdapter[] bodyAdapter = new TabMenu.MenuBodyAdapter[3];
    TabMenu.MenuTitleAdapter titleAdapter;
    TabMenu tabMenu;

    private File tempFile;
    int selTitle = 0;
    // Top按钮
    private Button btnOpen;
    private Button btnUndo;
    private Button btnSave;
    private Uri mImageUri;
    private Button btnScan;
    // 图像控件
    private ImageZoomView mZoomView;
    private ZoomState mZoomState;
    private SimpleZoomListener mZoomListener;
    ZoomControls zoomCtrl;
    // 处理用
    private RgbImage prevRgbImage = null;// 上一张图片
    private static RgbImage mRgbImage = null;
    private static RgbImage mSecRgbImage = null;
    private int r = 0;

    private int width;
    private int height;
    private int mSecWidth;
    private int mSecHeight;

    private ProgressDialog myProgressDialog;

    private void resetZoomState() {
        mZoomState.setPanX(0.5f);
        mZoomState.setPanY(0.5f);
        mZoomState.setZoom(1f);
        mZoomState.notifyObservers();
    }

    /**
     * @see android.app.Activity#onCreate(Bundle)
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题栏
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);// 去掉信息栏
        this.setContentView(R.layout.imagemain);
        // 设置分页栏的标题

        titleAdapter = new TabMenu.MenuTitleAdapter(this, new String[] { "常用",
                "设置"/* , "工具" */}, 16, 0xFF222222, Color.LTGRAY, Color.WHITE);
        // 定义每项分页栏的内容
        bodyAdapter[0] = new TabMenu.MenuBodyAdapter(this, new String[] { "截图",
                "添加文字", "左右翻转", "上下翻转", "旋转", "圆角"/* ,"图像合成" */}, new int[] {
                R.drawable.cutout, R.drawable.cutout, R.drawable.cutout,
                R.drawable.cutout, R.drawable.cutout, R.drawable.cutout }, 13,
                0xFFFFFFFF);

        bodyAdapter[1] = new TabMenu.MenuBodyAdapter(this, new String[] {
                "Red Filter", "Green Filter", "Blue Filter", "灰阶", "边缘检测",
                "模糊", "增加亮度" }, new int[] { R.drawable.sharpen,
                R.drawable.sharpen, R.drawable.sharpen, R.drawable.sharpen,
                R.drawable.sharpen, R.drawable.sharpen, R.drawable.sharpen },
                13, 0xFFFFFFFF);

        // bodyAdapter[2] = new TabMenu.MenuBodyAdapter(this, new String[] {
        // "工具1", "工具2", "工具3", "工具4" }, new int[] { R.drawable.save,
        // R.drawable.sharpen, R.drawable.window, R.drawable.compare },
        // 13, 0xFFFFFFFF);

        tabMenu = new TabMenu(this, new TitleClickEvent(),
                new BodyClickEvent(), titleAdapter, 0x55123456,// TabMenu的背景颜色
                R.style.PopupAnimation);// 出现与消失的动画

        tabMenu.update();
        tabMenu.SetTitleSelect(0);
        tabMenu.SetBodyAdapter(bodyAdapter[0]);

        // 打开文件
        btnOpen = (Button) findViewById(R.id.top_open);
        btnOpen.setOnClickListener(new Button.OnClickListener() {

            @Override
            public void onClick(View v) {
                if (mRgbImage != null) {
                    Dialog dialog = new AlertDialog.Builder(MainCanvas.this)
                            .setTitle("提示")
                            .setMessage("是否保存?")
                            .setPositiveButton("确定",
                                    new DialogInterface.OnClickListener() {

                                        @Override
                                        public void onClick(
                                                DialogInterface arg0, int arg1) {
                                            saveImage();
                                            openPhotoLibraryMenu();
                                        }
                                    })
                            .setNegativeButton("取消",
                                    new DialogInterface.OnClickListener() {

                                        @Override
                                        public void onClick(
                                                DialogInterface arg0, int arg1) {
                                            mRgbImage = null;
                                            openPhotoLibraryMenu();
                                        }
                                    }).create();
                    dialog.show();
                } else {
                    openPhotoLibraryMenu();
                }
            }
        });
        btnScan = (Button) findViewById(R.id.top_scan);
        btnScan.setOnClickListener(new Button.OnClickListener() {

            @Override
            public void onClick(View v) {
                allScan();
                Toast.makeText(MainCanvas.this, "扫描完成！", Toast.LENGTH_SHORT).show();
            }
        });
        // 撤销
        btnUndo = (Button) findViewById(R.id.top_undo);
        btnUndo.setOnClickListener(new Button.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                if (prevRgbImage != null) {
                    mRgbImage = (RgbImage) prevRgbImage.clone();
                    mZoomView.setImage(Bitmap.createBitmap(mRgbImage.getData(),
                            width, height, Bitmap.Config.ARGB_8888));
                }
            }
        });
        btnSave = (Button) findViewById(R.id.top_save);
        btnSave.setOnClickListener(new Button.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                if (mRgbImage != null) {
                    saveImage();
                } else {
                    Toast.makeText(MainCanvas.this, "请先选择图片",
                            Toast.LENGTH_SHORT).show();
                }
            }
        });
        // 图片
        mZoomView = (ImageZoomView) findViewById(R.id.zoomView);

        mZoomState = new ZoomState();
        mZoomView.setZoomState(mZoomState);
        mZoomListener = new SimpleZoomListener();
        mZoomListener.setZoomState(mZoomState);
        mZoomView.setOnTouchListener(mZoomListener);
        resetZoomState();
        Bitmap initMap = BitmapFactory.decodeResource(this.getResources(),
                R.drawable.screen);
        mZoomView.setImage(initMap);

        zoomCtrl = (ZoomControls) findViewById(R.id.zoomCtrl);
        zoomCtrl.setOnZoomInClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                float z = mZoomState.getZoom() + 0.25f;
                mZoomState.setZoom(z);
                mZoomState.notifyObservers();
            }
        });
        zoomCtrl.setOnZoomOutClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                float z = mZoomState.getZoom() - 0.25f;
                mZoomState.setZoom(z);
                mZoomState.notifyObservers();
            }
        });
    }

    class TitleClickEvent implements OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            selTitle = arg2;
            tabMenu.SetTitleSelect(arg2);
            tabMenu.SetBodyAdapter(bodyAdapter[arg2]);
        }
    }

    private int saveType = 0;
    private String saveTypeName = ".png";
    private int saveCompress = 0;

    // 保存
    private void saveImage() {
        LayoutInflater inflater = getLayoutInflater();
        final View layout = inflater.inflate(R.layout.saveimage,
                (ViewGroup) findViewById(R.id.saveLayout));
        final EditText edit = (EditText) layout.findViewById(R.id.fileName);
        RadioGroup group = (RadioGroup) layout.findViewById(R.id.radioGroup1);
        final RadioButton pngRadio = (RadioButton) group
                .findViewById(R.id.radioPng);
        RadioButton jpgRadio = (RadioButton) group.findViewById(R.id.radioJpg);
        group.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(RadioGroup arg0, int arg1) {
                if (arg1 == pngRadio.getId()) {
                    saveType = FORMAT_PNG;
                    saveTypeName = ".png";
                } else {
                    saveType = FORMAT_JPG;
                    saveTypeName = ".jpg";
                }
            }
        });
        SeekBar seekbar = (SeekBar) layout.findViewById(R.id.seekBar1);

        final TextView seekBarTitle = (TextView) layout
                .findViewById(R.id.seekBarTitle);
        seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress,
                    boolean fromUser) {
                seekBarTitle.setText(progress + "%");
                saveCompress = progress;
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub

            }
        });
        final AlertDialog show = new AlertDialog.Builder(

        MainCanvas.this).setTitle("请输入文件名")
                .setIcon(android.R.drawable.ic_dialog_info).setView(layout)
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface arg0, int arg1) {
                        try {

                            String name = edit.getText().toString();

                            String filename = FileHelper.getSaveImagePath(name
                                    + saveTypeName);
                            Log.d(TAG, "save file name is " + filename);
                            FileHelper.createSaveFolder();
                            if (FileHelper.fileExists(name + saveTypeName)) {
                                Toast.makeText(MainCanvas.this,
                                        "已存在文件，请重新输入文件名", Toast.LENGTH_LONG)
                                        .show();
                            } else {
                                saveFormat(saveType, filename, saveCompress);
                                Toast.makeText(MainCanvas.this, "保存成功",
                                        Toast.LENGTH_SHORT).show();
                                mRgbImage=null;
                            }

                        } catch (Exception ex) {
                            ex.printStackTrace();
                            Toast.makeText(MainCanvas.this, "保存失败",
                                    Toast.LENGTH_SHORT).show();
                        }
                    }
                }).setNegativeButton("取消", null).show();
    }

    class BodyClickEvent implements OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            tabMenu.SetBodySelect(arg2, Color.GRAY);
            // String str = "第" + String.valueOf(selTitle) + "栏\n\r" + "第"
            // + String.valueOf(arg2) + "项";

            // Toast.makeText(MainCanvas.this, str, 500).show();
            if (mRgbImage != null) {

                // 裁剪图片
                if (selTitle == 0 && arg2 == 0) {
                    cropImage();
                }
                // 添加文字
                if (selTitle == 0 && arg2 == 1) {
                    drawTextDialog();

                }
                // 左右翻转
                if (selTitle == 0 && arg2 == 2) {
                    Bitmap bitmap = Bitmap.createBitmap(mRgbImage.getData(),
                            width, height, Bitmap.Config.ARGB_8888);
                    bitmap = ImageHelper.gerZoomRotateBitmap(bitmap, -1, 1);
                    mRgbImage = RgbImageAndroid.toRgbImage(bitmap);
                    mZoomView.setImage(bitmap);
                }
                if (selTitle == 0 && arg2 == 3) {
                    Bitmap bitmap = Bitmap.createBitmap(mRgbImage.getData(),
                            width, height, Bitmap.Config.ARGB_8888);
                    bitmap = ImageHelper.gerZoomRotateBitmap(bitmap, 1, -1);
                    mRgbImage = RgbImageAndroid.toRgbImage(bitmap);
                    mZoomView.setImage(bitmap);
                }
                if (selTitle == 0 && arg2 == 4) {

                    // EditText t = new EditText(MainCanvas.this);
                    SeekBar bar = new SeekBar(MainCanvas.this);
                    bar.setMax(360);
                    bar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

                        @Override
                        public void onProgressChanged(SeekBar arg0, int arg1,
                                boolean arg2) {
                            r = arg1;
                        }

                        @Override
                        public void onStartTrackingTouch(SeekBar arg0) {
                            // TODO Auto-generated method stub

                        }

                        @Override
                        public void onStopTrackingTouch(SeekBar arg0) {
                            // TODO Auto-generated method stub

                        }
                    });
                    final AlertDialog show = new AlertDialog.Builder(
                            MainCanvas.this)
                            .setTitle("请输入")
                            .setIcon(android.R.drawable.ic_dialog_info)
                            .setView(bar)
                            .setPositiveButton("确定",
                                    new DialogInterface.OnClickListener() {

                                        @Override
                                        public void onClick(
                                                DialogInterface arg0, int arg1) {
                                            try {
                                                Bitmap bitmap = Bitmap.createBitmap(
                                                        mRgbImage.getData(),
                                                        width, height,
                                                        Bitmap.Config.ARGB_8888);
                                                bitmap = ImageHelper
                                                        .rotateBitmap(bitmap, r);
                                                width = bitmap.getWidth();
                                                height = bitmap.getHeight();
                                                mRgbImage = RgbImageAndroid
                                                        .toRgbImage(bitmap);
                                                mZoomView.setImage(bitmap);

                                            } catch (Exception ex) {

                                            }
                                        }
                                    }).setNegativeButton("取消", null).show();
                }

                if (selTitle == 0 && arg2 == 5) {
                    Bitmap bitmap = Bitmap.createBitmap(mRgbImage.getData(),
                            width, height, Bitmap.Config.ARGB_8888);
                    bitmap = ImageHelper.getRoundedCornerBitmap(bitmap);
                    width = bitmap.getWidth();
                    height = bitmap.getHeight();
                    mRgbImage = RgbImageAndroid.toRgbImage(bitmap);
                    mZoomView.setImage(bitmap);
                }

                if (selTitle == 0 && arg2 == 1) {
                }

                // 颜色过滤和增强
                if (selTitle == 1 && arg2 == 0) {
                    showOnlyRed();
                    reImage();
                }

                if (selTitle == 1 && arg2 == 1) {
                    showOnlyGreen();
                    reImage();
                }

                if (selTitle == 1 && arg2 == 2) {
                    showOnlyBlue();
                    reImage();
                }

                if (selTitle == 1 && arg2 == 3) {
                    greyScale(true);
                    reImage();
                }

                if (selTitle == 1 && arg2 == 4) {
                    sobel();
                    reImage();
                }

                if (selTitle == 1 && arg2 == 5) {
                    double[] template = { (1 / 9.0), (1 / 9.0), (1 / 9.0),
                            (1 / 9.0), (1 / 9.0), (1 / 9.0), (1 / 9.0),
                            (1 / 9.0), (1 / 9.0) };
                    convolve(template, 3, 3);
                    reImage();
                }
                if (selTitle == 1 && arg2 == 6) {
                    brightness();
                    reImage();
                }
//                if (selTitle == 1 && arg2 == 7) {
//                    rgbSubSample();
//                    reImage();
//                }
            } else {
                Toast.makeText(MainCanvas.this, "请先打开图片", Toast.LENGTH_SHORT)
                        .show();
            }
        }
    }

    private void reImage() {
        Bitmap bitmap = Bitmap.createBitmap(mRgbImage.getData(), width, height,
                Bitmap.Config.ARGB_8888);
        mZoomView.setImage(bitmap);
    }

    private void showOnlyRed() {
        thresholdColorPixels(0, 255, 255);
    }

    public void showOnlyGreen() {
        thresholdColorPixels(255, 0, 255);

    }

    public void showOnlyBlue() {
        thresholdColorPixels(255, 255, 0);
    }

    public void greyScale(boolean storePrevious) {
        int[] rgbData = mRgbImage.getData();
        if (storePrevious) {
            prevRgbImage = (RgbImage) mRgbImage.clone();
        }

        for (int y = 0; y < height; y++) {
            int outputOffset = y * width;
            for (int x = 0; x < width; x++) {
                int index = outputOffset + x;

                int R = ((rgbData[index] >> 16) & 0xff);
                int G = ((rgbData[index] >> 8) & 0xff);
                int B = ((rgbData[index]) & 0xff);

                int grey = (R + G + B) / 3;

                rgbData[index] = 0xff000000 | (grey << 16) | (grey << 8) | grey;

            }
        }
    }

    public void sobel() {
        prevRgbImage = (RgbImage) mRgbImage.clone();

        float[] template = { -1, 0, 1, -2, 0, 2, -1, 0, 1 };

        int templateSize = 3;

        int[] rgbData = mRgbImage.getData();
        int[] total = new int[width * height];
        int sumY = 0;
        int sumX = 0;
        int max = 0;
        for (int n = 0; n < 1; n++) {

            for (int x = (templateSize - 1) / 2; x < width - (templateSize + 1)
                    / 2; x++) {
                for (int y = (templateSize - 1) / 2; y < height
                        - (templateSize + 1) / 2; y++) {
                    sumY = 0;
                    for (int x1 = 0; x1 < templateSize; x1++) {
                        for (int y1 = 0; y1 < templateSize; y1++) {
                            int x2 = (x - (templateSize - 1) / 2 + x1);
                            int y2 = (y - (templateSize - 1) / 2 + y1);
                            float value = (rgbData[y2 * width + x2] & 0xff)
                                    * (template[y1 * templateSize + x1]);

                            sumY += value;
                        }
                    }

                    sumX = 0;

                    for (int x1 = 0; x1 < templateSize; x1++) {
                        for (int y1 = 0; y1 < templateSize; y1++) {
                            int x2 = (x - (templateSize - 1) / 2 + x1);
                            int y2 = (y - (templateSize - 1) / 2 + y1);
                            float value = (rgbData[y2 * width + x2] & 0xff)
                                    * (template[x1 * templateSize + y1]);

                            sumX += value;
                        }
                    }
                    total[y * width + x] = (int) Math.sqrt(sumX * sumX + sumY
                            * sumY);

                    if (max < total[y * width + x])
                        max = total[y * width + x];
                }
            }

            float ratio = (float) max / 255;

            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    sumX = (int) (total[y * width + x] / ratio);
                    total[y * width + x] = 0xff000000 | ((int) sumX << 16
                            | (int) sumX << 8 | (int) sumX);
                }
            }
        }
        System.arraycopy(total, 0, rgbData, 0, width * height);

    }

    private void sharp() {
        int[] rgbData = mRgbImage.getData();
        int[] total = new int[width * height];
        for (int i = 0; i < height - 1; i++) {
            for (int j = 0; j < width - 1; j++) {

                int red6 = ((rgbData[i * width + j + 1] >> 16) & 0xff);
                int red5 = ((rgbData[i * width + j] >> 16) & 0xff);
                int red8 = ((rgbData[(i + 1) * width + j] >> 16) & 0xff);
                int sharpRed = Math.abs(red6 - red5) + Math.abs(red8 - red5);

                int green6 = ((rgbData[i * width + j] >> 8) & 0xff);
                int green5 = ((rgbData[i * width + j + 1] >> 8) & 0xff);
                int green8 = ((rgbData[(i + 1) * width + j] >> 8) & 0xff);
                int sharpGreen = Math.abs(green6 - green5)
                        + Math.abs(green8 - green5);

                int blue6 = ((rgbData[i * width + j]) & 0xff);
                int blue5 = ((rgbData[i * width + j + 1]) & 0xff);
                int blue8 = ((rgbData[(i + 1) * width + j]) & 0xff);
                int sharpBlue = Math.abs(blue6 - blue5)
                        + Math.abs(blue8 - blue5);

                if (sharpRed > 255) {
                    sharpRed = 255;
                }
                if (sharpGreen > 255) {
                    sharpGreen = 255;
                }
                if (sharpBlue > 255) {
                    sharpBlue = 255;
                }
                total[i * width + j] = 0xff000000 | ((int) sharpRed << 16
                        | (int) sharpGreen << 8 | (int) sharpBlue);

            }

        }
        System.arraycopy(total, 0, rgbData, 0, width * height);
    }

    /*
     * 亮度调节
     */
    private void brightness() {
        RgbAdjustBrightness bright = new RgbAdjustBrightness(300, 300, 300);
        try {
            bright.push(mRgbImage);
            mRgbImage = (RgbImage) bright.getFront();
        } catch (Error e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private void crop() {
        try {
            Gray16Crop crop = new Gray16Crop(10, 10, width, height);
            crop.push(mRgbImage);
            mRgbImage=(RgbImage) crop.getFront();
        } catch (Error e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    private void rgbSubSample() {
        try {
            
            RgbStretch shrink = new RgbStretch(width,height);
            shrink.push(mRgbImage);
            mRgbImage=(RgbImage) shrink.getFront();
        } catch (Error e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    

    public void convolve(double[] mat, int rows, int cols) {
        showProgress();
        if ((rows % 2) == 0 || (cols % 2) == 0) {
        } else {
            // start = (int) System.currentTimeMillis();

            int[] rgbData = mRgbImage.getData();
            int[] conv = new int[width * height];
            int sumR = 0;
            int sumG = 0;
            int sumB = 0;

            prevRgbImage = (RgbImage) mRgbImage.clone();

            for (int x = (cols - 1) / 2; x < width - (cols + 1) / 2; x++) {
                for (int y = (rows - 1) / 2; y < height - (rows + 1) / 2; y++) {
                    sumR = 0;
                    sumG = 0;
                    sumB = 0;

                    for (int x1 = 0; x1 < cols; x1++) {
                        for (int y1 = 0; y1 < rows; y1++) {
                            int x2 = (x - (cols - 1) / 2 + x1);
                            int y2 = (y - (rows - 1) / 2 + y1);
                            int R = ((rgbData[y2 * width + x2] >> 16) & 0xff);
                            int G = ((rgbData[y2 * width + x2] >> 8) & 0xff);
                            int B = ((rgbData[y2 * width + x2]) & 0xff);

                            sumR += R * (mat[y1 * cols + x1]);

                            sumG += G * (mat[y1 * cols + x1]);
                            sumB += B * (mat[y1 * cols + x1]);
                        }
                    }

                    conv[y * width + x] = 0xff000000 | ((int) sumR << 16
                            | (int) sumG << 8 | (int) sumB);
                }
            }
            System.arraycopy(conv, 0, rgbData, 0, width * height);
            // end = (int) System.currentTimeMillis();
            myProgressDialog.dismiss();
        }
    }

    @Override
    /**  
     * 创建MENU  
     */
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add("menu");// 必须创建一项
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    /**  
     * 拦截MENU  
     */
    public boolean onMenuOpened(int featureId, Menu menu) {
        if (tabMenu != null) {
            if (tabMenu.isShowing())
                tabMenu.dismiss();
            else {
                tabMenu.showAtLocation(findViewById(R.id.LinearLayout01),
                        Gravity.BOTTOM, 0, 0);
            }
        }
        return false;// 返回为true 则显示系统menu
    }

    public void cropImage() {
        if (mImageUri != null) {

            try {

                String mfileurl = getAbsoluteImagePath(mImageUri);
                Log.d(TAG, mfileurl);
                File mfile = new File(mfileurl);
                tempFile = new File(FileHelper.getBasePath() + "/temp.jpg");

                Intent intent = new Intent("com.android.camera.action.CROP");

                intent.setDataAndType(Uri.fromFile(mfile), "image/*");// 设置要裁剪的图片

                intent.putExtra("crop", "true");// crop=true 有这句才能出来最后的裁剪页面.

                /*
                 * intent.putExtra("aspectX", 1);// 这两项为裁剪框的比例.
                 * 
                 * intent.putExtra("aspectY", 1);// x:y=1:1
                 * 
                 * // 如果不设置aspectX和aspectY，则可以以任意比例缩放
                 */

                /*
                 * intent.putExtra("outputX", 96);
                 * 
                 * intent.putExtra("outputY", 96);//设置为96*96
                 */

                intent.putExtra("output", Uri.fromFile(tempFile));// 保存到临时目录

                intent.putExtra("outputFormat", "JPEG");// 返回格式

                startActivityForResult(intent, 2);
            } catch (IOException e) {

                e.printStackTrace();
            }
        } else {
            Toast.makeText(this, "请选择图片", Toast.LENGTH_SHORT).show();
        }

    }

    /**
     * 
     * 裁剪完图片后系统调用的方法:onActivityResult
     */

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        Log.d(TAG, "activity result=" + resultCode);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
            case REQUEST_PHOTO_LIBRARY:// 打开文件

                mImageUri = data.getData();

                ContentResolver cr = this.getContentResolver();
                try {

                    Bitmap bitmap = BitmapFactory.decodeStream(cr
                            .openInputStream(mImageUri));
                    setJpegData(bitmap);
                    mZoomView.setImage(bitmap);

                } catch (FileNotFoundException ex) {
                    Toast.makeText(getBaseContext(), "图片未找到",
                            Toast.LENGTH_SHORT).show();
                } catch (java.lang.OutOfMemoryError ex) {
                    Toast.makeText(this, "图片大小超过限制", Toast.LENGTH_SHORT).show();
                }
                break;
            case CROP_IMAGE:// 裁剪图片

                if (tempFile != null) {
                    try {
                        ContentResolver cr1 = this.getContentResolver();
                        Bitmap bitmap = BitmapFactory.decodeStream(cr1
                                .openInputStream(Uri.fromFile(tempFile)));
                        setJpegData(bitmap);

                        mZoomView.setImage(bitmap);
                    } catch (FileNotFoundException ex) {
                        Toast.makeText(getBaseContext(), "图片未找到",
                                Toast.LENGTH_SHORT).show();
                    } catch (java.lang.OutOfMemoryError ex) {
                        Toast.makeText(this, "图片大小超过限制", Toast.LENGTH_SHORT)
                                .show();
                    }
                }
                break;
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    // 打开图库选择文件
    protected void openPhotoLibraryMenu() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("image/*");
        startActivityForResult(intent, REQUEST_PHOTO_LIBRARY);
    }

    public void setJpegData(byte[] jpegData) {
        Bitmap bitmap = BitmapFactory.decodeByteArray(jpegData, 0,
                jpegData.length, null);
        mRgbImage = RgbImageAndroid.toRgbImage(bitmap);
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        bitmap.getPixels(mRgbImage.getData(), 0, width, 0, 0, width, height);
    }

    public void setJpegData(Bitmap temp) {
        try {
            Bitmap bitmap = temp.copy(Bitmap.Config.ARGB_8888, true);
            mRgbImage = RgbImageAndroid.toRgbImage(bitmap);
            width = bitmap.getWidth();
            height = bitmap.getHeight();
            bitmap.getPixels(mRgbImage.getData(), 0, width, 0, 0, width, height);
        } catch (java.lang.OutOfMemoryError ex) {
            Toast.makeText(this, "图片大小超过限制", Toast.LENGTH_SHORT).show();
            mRgbImage = null;
        }
    }

    public void setSecJpegData(Bitmap temp) {
        Bitmap bitmap = temp.copy(Bitmap.Config.ARGB_8888, true);
        mSecRgbImage = RgbImageAndroid.toRgbImage(bitmap);
        mSecWidth = bitmap.getWidth();
        mSecHeight = bitmap.getHeight();
        bitmap.getPixels(mSecRgbImage.getData(), 0, mSecWidth, 0, 0, mSecWidth,
                mSecHeight);

    }

    // 颜色过滤
    public void thresholdColorPixels(int rthresh, int gthresh, int bthresh) {

        int[] rgbData = mRgbImage.getData();
        prevRgbImage = (RgbImage) mRgbImage.clone();
        // 计时用
        // start = (int) System.currentTimeMillis();
        for (int y = 0; y < height; y++) {
            int outputOffset = y * width;
            for (int x = 0; x < width; x++) {
                int index = outputOffset + x;

                int R = ((rgbData[index] >> 16) & 0xff);
                int G = ((rgbData[index] >> 8) & 0xff);
                int B = ((rgbData[index]) & 0xff);

                if (R <= rthresh) {
                    R = 0;
                }
                if (G <= gthresh) {
                    G = 0;
                }
                if (B <= bthresh) {
                    B = 0;
                }

                rgbData[index] = 0xff000000 | (R << 16) | (G << 8) | B;
            }
        }
        // end = (int) System.currentTimeMillis();
    }

    protected String getAbsoluteImagePath(Uri uri) {
        // can post image
        String[] proj = { MediaStore.Images.Media.DATA };
        Cursor cursor = managedQuery(uri, proj, // Which columns to return
                null, // WHERE clause; which rows to return (all rows)
                null, // WHERE clause selection arguments (none)
                null); // Order-by clause (ascending by name)

        int column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();

        return cursor.getString(column_index);
    }

    private void drawTextDialog() {
        LayoutInflater inflater = getLayoutInflater();
        final View layout = inflater.inflate(R.layout.image_text,
                (ViewGroup) findViewById(R.id.imageText_layout));
        DialogInterface.OnClickListener okListener = new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface arg0, int arg1) {
                EditText mEdit;
                EditText mEditSize;
                EditText mEditX;
                EditText mEditY;
                mEdit = (EditText) layout.findViewById(R.id.edit_text);
                mEditSize = (EditText) layout.findViewById(R.id.edit_size);
                mEditX = (EditText) layout.findViewById(R.id.image_text_x);
                mEditY = (EditText) layout.findViewById(R.id.image_text_y);
                String strText = mEdit.getText().toString();
                String strSize = mEditSize.getText().toString();
                String strX = mEditX.getText().toString();
                String strY = mEditY.getText().toString();

                onActionText(strText, strSize, strX, strY);
            }

        };
        new AlertDialog.Builder(this).setTitle("添加文字").setView(layout)
                .setPositiveButton("确定", okListener)
                .setNegativeButton("取消", null).show();

    }

    private void onActionText(String strText, String strSize, String strX,
            String strY) {
        Log.d(TAG, "onActionText,strText=" + strText + " strSize=" + strSize
                + " strX=" + strX + "strY" + strY);
        if (strText.length() <= 0) {
            return;
        }
        if (strSize.length() <= 0) {
            return;
        }
        int nSize = 0;
        int x = 0, y = 0;
        try {
            nSize = Integer.parseInt(strSize);
            x = Integer.parseInt(strX);
            y = Integer.parseInt(strY);
        } catch (Exception e) {
            return;
        }
        try {
            Bitmap bm = Bitmap.createBitmap(mRgbImage.getData(), width, height,
                    Bitmap.Config.ARGB_8888);
            Bitmap b = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(),
                    Bitmap.Config.ARGB_8888);
            Canvas c = new Canvas(b);
            Paint paint = new Paint();
            c.drawBitmap(bm, 0, 0, paint);

            String familyName = "宋体";
            Typeface font = Typeface.create(familyName, Typeface.BOLD);
            paint.setColor(Color.RED);
            paint.setTypeface(font);
            paint.setTextSize(nSize);
            c.drawText(strText, x, y, paint);
            c.save(Canvas.ALL_SAVE_FLAG);
            c.restore();

            mRgbImage = RgbImageAndroid.toRgbImage(b);
            reImage();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void showProgress() {
        myProgressDialog = ProgressDialog.show(MainCanvas.this, "处理中...",
                "计算时间较长，请稍等", true, false);
        myProgressDialog.show();

    }

    private void showScanProgress() {
        
    }

    /**
     * 转换图片为指定格式
     * 
     * @param nFormat
     */
    private void saveFormat(int nFormat, String strPictureFile, int compress) {
        switch (nFormat) {
        case FORMAT_JPG:
            try {
                Bitmap bm = Bitmap.createBitmap(mRgbImage.getData(), width,
                        height, Bitmap.Config.ARGB_8888);

                File file = new File(strPictureFile);
                if (!file.exists()) {// 文件存在返回false
                    file.createNewFile();// 创建一个文件
                }
                FileOutputStream fos = new FileOutputStream(strPictureFile);
                bm.compress(CompressFormat.JPEG, compress, fos);

                fos.flush();
                fos.close();

            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            break;
        case FORMAT_PNG:
            FileOutputStream fos = null;
            try {
                Bitmap bm = Bitmap.createBitmap(mRgbImage.getData(), width,
                        height, Bitmap.Config.ARGB_8888);

                File file = new File(strPictureFile);
                if (!file.exists()) {// 文件存在返回false
                    file.createNewFile();// 创建一个文件
                }
                fos = new FileOutputStream(strPictureFile);

                bm.compress(CompressFormat.PNG, compress, fos);

                fos.flush();
                fos.close();

            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            break;
        }
    }

    /**
     * 扫描整个媒体
     */
    public void allScan() {
        sendBroadcast(new Intent(
                Intent.ACTION_MEDIA_MOUNTED,
                Uri.parse("file://" + Environment.getExternalStorageDirectory())));
    }

}
